function saveBook(){
	
	var DEFAULT_BOOK_NAME = "load.plist"
	
	//create empty book
	var bookName = $.trim( $('#book-name-input').val() ) || DEFAULT_BOOK_NAME;
	var b = new book(bookName);
	
	//add scenes
	$.each(sceneList.scenes, function(i,e){
		
		var sceneName = e.item.attr('scenename');
		sceneName =  $.trim(sceneName);
		var scene = b.addScene(sceneName);
		
		scene.showNextBtn = e.nextBtn;
		scene.showPrevBtn = e.prevBtn;
		if (e.snapshot){
			scene.snapshot = e.snapshot;
		}
		scene.batchNodes = e.batchNodes.getAsArray();
			
		_addTreeActors(e.tree.treeView.dataSource.data(), scene)

	});
	
	function _addTreeActors(actors, scene){
		
		$.each(actors, function(i,e){
		
			//create an actor
			var actorName = e.text;
			var actor = scene.addActor(actorName);
			
			//set actor attributes
			var fe = e.imageObj;
			if (fe.getText){
				
				actor.text = fe.getText();	
				actor.color = fe.getFill();
				
				//en el canvas se usa el attr fontFamily
				//font es el attr que almacena el verdadero font seleccionado por el usuario
				actor.fontName = e.font;
				
				actor.fontSize = fe.get('fontSize');
				actor.fontAlignment = fe.get('textAlign');
				actor.type = "textType";			
				actor.textSize = "" + fe.getWidth().toFixed(0) + "," + fe.getHeight().toFixed(0);
			}
			else {
				//En local no funciona porque no contiene el = de la llamada al servicio
				actor.image = e.source.split('=')[1];
				actor.type = "actorType";
			}
			
			actor.name = e.text;
			actor.draggable = e.draggable;
			actor.touchable = e.touchable;
			actor.rotation  = fe.getAngle();
			
			var w = (fe.getLeft() / deviceController.canvasRatio).toFixed(0);
			var t = (fe.getTop() / deviceController.canvasRatio).toFixed(0);
			t = deviceController.getCocosHeight(t);
			
			actor.position = w + "," + t; 
			actor.scale = (fe.getScaleX() / deviceController.canvasRatio).toFixed(2) + "," +  (fe.getScaleY() / deviceController.canvasRatio).toFixed(2);
			actor.zindex = fe.get('zindex');
			actor.group = e.group;
			actor.initState = e.initState;
			actor.opacity = fe.getOpacity();
			
			if ( e.batchNode){
				actor.batchNode = e.batchNode;	
			}
			

			_addActorActions(e, actor);
			
			//add element childrens
			if (e.hasChildren){
				
				var childrens = e.children.data();
				_addTreeActors(childrens, actor)
			}
				
		});//end each
		
	}
	
	function _addActorActions(e, actor){
		
		if (e.sequences){
			
			$.each(e.sequences, function(i,s){
				
				if (s.actions && s.actions.length){
					
					var firstAction = s.actions[0].action;
					
					var sequenceName = actor.addSequence(i, firstAction, s.repeat);
					
					$.each(s.actions, function(j,a){
					
						var action = actor.addAction(sequenceName, a.action);
						
						var aux = {};
						$.extend(aux, a.action);
					
						action.name = aux.name;
						delete aux.name;
						
						if (aux.hasOwnProperty('duration')){
							action.duration = aux.duration;
							delete aux.duration;
						}
						if (aux.hasOwnProperty('fx')){
							action.fx = aux.fx;
							delete aux.fx;
						}
						if (aux.type != "DDSpawn"){
							action.repeat = aux.repeat;
						}
						delete aux.repeat;
						
						action.type = aux.type;
						delete aux.type;

						//Se eliminan las propiedades básicas para buscar propiedades específicas de cada tipo de accion
						delete aux.event;
						delete aux.state;
			
						if (!$.isEmptyObject(aux)){
							
							if (action.type == "DDSpawn"){
								
								action.spawnActions = spawnProperties(aux.cfg1);
							}
							else {
								
								action.actionParameters = [];
								
								$.each(aux, function(key, elem){
									
									//los atributos move y scale van en un mismo string
									if (key == "cfg11"){
										
										if (action.type == "DDMoveTo") {
											
											elem = deviceController.getCocosHeight(elem);
										}
										
										action.actionParameters[0] += "," + elem
									}
									else {
										action.actionParameters[action.actionParameters.length] = elem
									}
								})
							}
							
							
						}
						
						
					})
				}
			});
			
		}
		
	}
	
	
	function spawnProperties(spawnActions){
		
		if (!spawnActions) return null;
		
		var r = {};
		
		$.each(spawnActions, function(i,e){
			
			var action = {};
			var aux = {};
			$.extend(aux, e);
			
			action.name = aux.name;
			delete aux.name;
			
			if (aux.hasOwnProperty('duration')){
				action.duration = aux.duration;
				delete aux.duration;
			}
			if (aux.hasOwnProperty('fx')){
				action.fx = aux.fx;
				delete aux.fx;
			}
			if (aux.type != "DDSpawn"){
				action.repeat = aux.repeat;
			}
			delete aux.repeat;
			
			action.type = aux.type;
			delete aux.type;

			//Se eliminan las propiedades básicas para buscar propiedades específicas de cada tipo de accion
			delete aux.event;
			delete aux.state;

			if (!$.isEmptyObject(aux)){
				
				if (action.type == "DDSpawn"){
					
					action.spawnActions = aux.cfg1;
				}
				else {
					
					action.actionParameters = [];
					
					$.each(aux, function(key, elem){
						
						//los atributos move y scale van en un mismo string
						if (key == "cfg11"){
							
							if (action.type == "DDMoveTo") {
								
								elem = deviceController.getCocosHeight(elem);
							}
							
							action.actionParameters[0] += "," + elem
						}
						else {
							action.actionParameters[action.actionParameters.length] = elem
						}
					})
				}
				
				
			}
			
			r[action.name] = action;
		})
		
		return r;
	}
	
	return b;
}